#include "ToolsFunctions.h"
 #include "OrientationImage.h"
 #include "svm.h"

 #define TRAIN 0
 #define TEST 1
char classes[1024];
 struct pointGraph{
         float valeur;
         int classe;
         int indice;
 };
 typedef struct pointGraph PointGraph;

 void creerGraph(char * fichierEntree,char * fichierTraining){
         //Precision TP/FP+TP
         //Rappel TP/FP
         FILE * fEntree,* fSortie;
         int ligne;
         int nbElements=0;
         int nbPositif=0;
         int *points;
         float **leGraph;
         char fic[1024];
         PointGraph *lesPoints;
         int i=0,j;
         fEntree = fopen(fichierEntree,"r");
         if(fEntree == NULL){
                 printf("Erreur :Lecture fichier\n");
                 return 1;
         }

         while(fscanf(fEntree,"%s %d",fic,&ligne)!=EOF){
                 nbElements++;
                 if(ligne==1)nbPositif++;

         }
         printf("%f\n",nbPositif/(float)nbElements);
         //system("pause");
         fclose(fEntree);
         fEntree = fopen(fichierEntree,"r");
         fSortie = fopen(fichierTraining,"r");
         if(fSortie==NULL){
                 fclose(fEntree);
                 return 1;
         }
         points = (int*)calloc(nbElements,sizeof(int));
         lesPoints=(PointGraph*)calloc(nbElements,sizeof(PointGraph));
         while(fscanf(fEntree,"%s %d",fic,&ligne)!=EOF){
                 points[i]=ligne;
                 fscanf(fSortie,"%f\n",&lesPoints[i].valeur);
                 lesPoints[i].indice = i;
                 if(lesPoints[i].valeur >= 0)lesPoints[i].classe =1;
                 else lesPoints[i].classe = -1;
                 i++;
         }
         printf("%d\n",nbPositif);
         int min;
         fclose(fEntree);
         fclose(fSortie);

         //Tri du tableau
         PointGraph temp;
         for(i=0;i<nbElements-1;i++){
                 min=i;
                 for(j=i+1;j<nbElements;j++){
                         if(lesPoints[j].valeur>lesPoints[min].valeur){
                                 min=j;
                         }
                 }
                 temp=lesPoints[i];
                 lesPoints[i] = lesPoints[min];
                 lesPoints[min]=temp;
         }
         printf("ok\n");
         int nbFP,nbFN,nbVP,nbVN,nbP;
         nbFP=nbFN=nbVP=nbVN=nbP=0;
         leGraph = (float**)calloc(nbElements,sizeof(float*));
         FILE* sortie=fopen("graph.txt","w");
         for(i=0;i<nbElements;i++){
                 leGraph[i]=(float*)calloc(2,sizeof(float));
                 if(points[lesPoints[i].indice]>=0)nbVP++;

 //              if(lesPoints[i].classe>=0){
 //                      if(points[lesPoints[i].indice]>=0)nbVP++;
 //                      else nbFP++;
 //              }
 //              else{
 //                      if(points[lesPoints[i].indice]<0)nbVN++;
 //                      else nbFN++;
 //              }
                 leGraph[i][0]=(float)(nbVP/(float)(nbPositif));
                 //leGraph[i][1]=(float)(nbVP/(nbVP+nbFP));
                 leGraph[i][1]=(float)(nbVP/(float)(i+1));
                 if(leGraph[i][1]>1)
                         printf("%d %d %f\n",i,nbVP,leGraph[i][1]);
                 fprintf(sortie,"%f %f\n",leGraph[i][0],leGraph[i][1]);
         }
         printf("ok\n");
         fclose(sortie);

         int k=0;
         //Average Precision
         //Parcours des 11 points de fonctionnement
         //      for(i=1;i<10;i++){
         //              k=0;
         //              //Pour chaque point de fonctionnement recherche du point dans le tableau
         //              for(j=1;j<nbElements;j++){
         //                      if(leGraph[j][0]>=(float)i*0.1){
         //                              k=j-1;
         //                              break;
         //                      }
         //              }
         //              //Si ce n'est pas l'origine on cherche la valeur en y supÃ©rieur maximum aprÃ¨s k
         //              if(k!=0){
         //                      min = k;
         //                      for(j=k+1;j<nbElements;j++){
         //                              if(leGraph[j][1]>leGraph[min][1]){
         //                                      min = j;
         //                              }
         //                      }
         //                      //On remplace le y du point de fonctionnement
         //                      leGraph[k]=leGraph[min];
         //              }
         //
         //
         //      }
         IplImage* image;
         CvSize taille;
         CvScalar scalaire = cvScalarAll(255);
         taille.height = 600;
         taille.width = 800;
         image = cvCreateImage(taille,IPL_DEPTH_32F,1);
         CvPoint pt1,pt2;
         for(i=0;i<800;i++){
                 for(j=0;j<600;j++){
                         cvSet2D(image,j,i,scalaire);
                 }
         }
         scalaire = cvScalarAll(0);

         //      for(i=0;i<nbElements;i++){
         //              leGraph[i][0] = (float)(((rand()%101)*1.0)/100);
         //              leGraph[i][1] = (float)(((rand()%101)*1.0)/100);
         //      }

         for(i=0;i<nbElements-1;i++){
                 pt1.x = 50+(700*leGraph[i][0]);
                 pt1.y = 550-(500*leGraph[i][1]);
                 pt2.x = 50+(700*leGraph[i+1][0]);
                 pt2.y = 550-(500*leGraph[i+1][1]);
                 cvLine(image,pt1,pt2,scalaire,1,8,0);
         }

         pt1 = cvPoint(50,550);
         pt2 = cvPoint(750,550);
         cvLine(image,pt1,pt2,scalaire,1,8,0);
         pt1 = cvPoint(50,50);
         pt2 = cvPoint(50,550);
         cvLine(image,pt1,pt2,scalaire,1,8,0);

         cvNamedWindow("Graphe", CV_WINDOW_AUTOSIZE);
         cvShowImage("Graphe", image);
         cvWaitKey(0);
         cvDestroyWindow("Graphe");

         cvSaveImage("graph.jpg",image,0);
         cvReleaseImage(&image);


         for(i=nbElements-1;i>=0;i--){
                 free(leGraph[i]);
         }
         free(leGraph);

         free(points);
         free(lesPoints);

 }

 void verifImages(){
         FILE* voitures = fopen("car.txt","r");
         int i,j;
         char nomFichier[1024];
         int classe;
         IplImage * img;
         IplImage * orig;
         while(fscanf(voitures,"%d %s\n",&classe,nomFichier) != EOF){
                 if(classe == 1){
                         img = cvLoadImage(nomFichier,0);
                         orig = cvCreateImage(cvGetSize(img), IPL_DEPTH_32F, 1);
                         cvConvertScale(img, orig, 1.0 / 255.0, 0);

                         if(cvCheckArr(img,NULL,0,0)==0){
                                 printf("erreur\n");
                         }

                         cvReleaseImage(&img);
                         cvReleaseImage(&orig);


                 }

         }
 }

 void proceedDescriptors(){

         int nbImages = 0,nbImagesTotal=0;
         int *centre;
         int hauteur;
         int nbPatch = 10000;
         int nbIter = 3;
         double **kmeansTab;
         double ***histos;
         double **tabTemp;
         double **unPatch;
         FILE* fPatch;
         char fic[15];

         int *visualsWords ;


         int i=0,j=0,l=0,k;

         int classe; // class of the image +/-1


         IplImage **iogg;
         IplImage *img;
         FILE* voitures,*fHogg;

         srand(time(NULL));

         char nomFichier[1024];
         char nomImage[10];
         char listeImages[1024];

         sprintf(listeImages,"test2007/VOCdevkit/VOC2007/ImageSets/Main/%s_test.txt",classes);
         //seekForClass("test2007/VOCdevkit/VOC2007/Annotations","car");
         voitures = fopen(listeImages,"r");
         while(fscanf(voitures,"%s %d",nomFichier,&classe) != EOF){
                 nbImagesTotal++;
         }
         fclose(voitures);

         //seekForClass("D:/Documents/Projet3A/Release/VOCdevkit/VOC2007/Annotations","car");
         sprintf(listeImages,"VOCdevkit/VOC2007/ImageSets/Main/%s_trainval.txt",classes);
         voitures = fopen(listeImages,"r");
         while(fscanf(voitures,"%s %d",nomFichier,&classe) != EOF){
                 if(classe == 1){
                         nbImages++;
                 }
                 nbImagesTotal++;

         }
         fclose(voitures);

         //histos = (double***)calloc(nbImages,sizeof(double**));
 //      for(i=0;i<nbImages;i++){
 //              histos[i]= (double**)calloc(nbPatch,sizeof(double*));
 //              for(j=0;j<nbPatch;j++){
 //                      histos[i][j]=(double*)calloc(DIMENSION,sizeof(double));
 //              }
 //      }
 //      ouep = (int*)calloc(nbImages*nbPatch,sizeof(int));
 //      system("pause");
         i=0;
         voitures = fopen(listeImages,"r");

         //fHogg = fopen("hogg.txt","w");
 //      for(i=0;i<nbImages;i++){
 //              histos[i] = (double**)calloc(nbPatch,sizeof(double*));
 //              for(j=0;j<nbPatch;j++){
 //                      histos[i][j]=(double*)calloc(DIMENSION,sizeof(double));
 //                      for(k=0;k<DIMENSION;k++){
 //                              histos[i][j][k]=(double)(rand()/(double)RAND_MAX);
 //                      }
 //              }
 //      }
         while(fscanf(voitures,"%s %d",nomImage,&classe) != EOF){

                 if(classe == 1){
						 sprintf(fic,"%s_%d.txt",classes,i);
						 fPatch = fopen(fic,"w");
                         printf("avant integral\n");
                         sprintf(nomFichier,"VOCdevkit/VOC2007/JPEGImages/%s.jpg",nomImage);

                         img = cvLoadImage(nomFichier,0);
                         iogg = integralImgOrient(nomFichier);

                         printf("apres integral\n");
                         unPatch=(double**)calloc(nbPatch,sizeof(double*));
                         //histos[i]=(double**)calloc(nbPatch,sizeof(double*));

                         for(j=0;j<nbPatch;j++){
                                 printf("avant patch\n");

                                 hauteur = 19;
                                 while(hauteur<20){
                                         if(cvGetSize(img).height<cvGetSize(img).width)hauteur = rand()%(cvGetSize(img).height/4);
                                         else hauteur = rand()%(cvGetSize(img).width/4);
                                 }

                                 centre=(int*)calloc(2,sizeof(int));
                                 centre[0]=(rand()%(cvGetSize(img).width-4*hauteur)) + 2*hauteur;
                                 centre[1]=(rand()%(cvGetSize(img).height-4*hauteur)) + 2*hauteur;

                                 tabTemp = patch(iogg,centre[0],centre[1],hauteur);
                                 printf("apres patch\n");
                                 //histos[i][j]=patchToHisto(tabTemp);
                                 unPatch[j]=patchToHisto(tabTemp);
                                 //reOrient(histos[i][j]);
                                 reOrient(unPatch[j]);
                                 //histo = patchToHisto(tabTemp);
 //                              for(l=0;l<DIMENSION;l++){
 //                                      fprintf(fHogg,"%lf ",histo[l]);
 //                              }
 //                              fprintf(fHogg,"\n");
                                 for(k=0;k<NB_CASES;k++){
                                         free(tabTemp[k]);
                                 }
                                 free(tabTemp);
                                 //free(histo);
                                 free(centre);
                         }
                         system("cls");
                         for(j=0;j<NB_ORIENT;j++){
                                 cvReleaseImage(&iogg[j]);
                         }
                         cvReleaseImage(&img);
                         free(img);
                         free(iogg);
                         for(j=0;j<nbPatch;j++){
                        	 for(k=0;k<DIMENSION;k++){
                        		 fprintf(fPatch,"%lf|",unPatch[j][k]);
                        	 }
                        	 fprintf(fPatch,"\n");
                         }
                         fclose(fPatch);
                         for(j=0;j<nbPatch;j++){
                        	 free(unPatch[j]);
                         }
                         free(unPatch);
                         //normalize(histos[i],nbPatch);
                         i++;
                 }
         }
         //fclose(fHogg);
         printf("PatchAppliquÃ©\n");
         fclose(voitures);
         //free(fHogg);
         system("cls");
         printf("avant kmeans\n");
         kmeansTab = kmeans2(NB_KMEANS,nbImages,nbIter,nbPatch,classes);
         //kmeansTab = kmeans(NB_KMEANS,histos,nbImages,nbIter,nbPatch);
         printf("apres kmeans\n");
//         for(i=0;i<nbImages;i++){
//                 for(j=0;j<nbPatch;j++){
//                         free(histos[i][j]);
//                 }
//                 free(histos[i]);
//         }
//         free(histos);
         //normalize(kmeansTab,NB_KMEANS);
         sprintf(listeImages,"%s_kmeans.txt",classes);
         FILE* fkmean = fopen(listeImages,"w");
         for(i=0;i<NB_KMEANS;i++){
                 for(j=0;j<DIMENSION;j++){
                         fprintf(fkmean,"%lf|",kmeansTab[i][j]);
                 }
                 fprintf(fkmean,"\n");
         }
         printf("Kmeans effectuÃ©s\n");
         fclose(fkmean);

         sprintf(listeImages,"VOCdevkit/VOC2007/ImageSets/Main/%s_trainval.txt",classes);
         voitures = fopen(listeImages,"r");
         sprintf(listeImages,"%s_sortie.txt",classes);
         FILE* fSortie = fopen(listeImages,"w");

         j=0;
         while(fscanf(voitures,"%s %d\n",nomImage,&classe) != EOF){
                 system("cls");
                 j++;
                 printf("Chargement %lf \%\n",(double)((double)(j/(double)nbImagesTotal)*(double)100));
                 //printf("avant comparaison\n");
                 sprintf(nomFichier,"VOCdevkit/VOC2007/JPEGImages/%s.jpg",nomImage);
                 visualsWords=compareToVisualWords(nomFichier,kmeansTab,nbPatch);
                 //printf("apres comparaison\n");
                 fprintf(fSortie,"%d ",classe);
                 for(i=0;i<NB_KMEANS;i++){
                         fprintf(fSortie,"%d:%f ",i+1,(float)(visualsWords[i]/(float)nbPatch));
                         //fprintf(fSortie,"%d:%d ",i+1,visualsWords[i]);
                 }
                 free(visualsWords);
                 fprintf(fSortie,"\n");


         }
         fclose(fSortie);
         fclose(voitures);
         free(fSortie);
         free(voitures);

         printf("Entrainement terminé\n");
        //seekForClass("D:/Documents/Projet3A/Release/test2007/VOCdevkit/VOC2007/Annotations","car");
         sprintf(listeImages,"test2007/VOCdevkit/VOC2007/ImageSets/Main/%s_test.txt",classes);
         voitures = fopen(listeImages,"r");
         sprintf(listeImages,"%s_sortie_test.txt",classes);
         fSortie = fopen(listeImages,"w");
         while(fscanf(voitures,"%s %d\n",nomImage,&classe) != EOF){
                 system("cls");
                 j++;
                 sprintf(nomFichier,"test2007/VOCdevkit/VOC2007/JPEGImages/%s.jpg",nomImage);
                 printf("Chargement %lf \%\n",(double)((double)(j/(double)nbImagesTotal)*(double)100));
                 //printf("avant comparaison\n");
                 visualsWords=compareToVisualWords(nomFichier,kmeansTab,nbPatch);
                 //printf("apres comparaison\n");
                 fprintf(fSortie,"0 ");
                 for(i=0;i<NB_KMEANS;i++){
                         fprintf(fSortie,"%d:%f ",i+1,(float)(visualsWords[i]/(float)nbPatch));
                         //fprintf(fSortie,"%d:%d ",i+1,visualsWords[i]);
                 }
                 free(visualsWords);
                 fprintf(fSortie,"\n");


         }
         printf("Visuals Words effectuÃ©s\n");
         fclose(fSortie);
         fclose(voitures);
         free(fSortie);
         free(voitures);

         for(i=0;i<NB_KMEANS;i++){
                 free(kmeansTab[i]);
         }
         free(kmeansTab);

 }


 int main(int argc, char **argv){

		 char nomFichier[1024];
		 printf("Veuillez saisir le nom de la classe/enter the class name please\n");
		 gets(classes);
         proceedDescriptors();
         //trainSVM("sortie.txt","modele","C:/SVMLight/svm_learn.exe");
         //testSVM("sortie_test.txt","modele","output.txt","C:/SVMLight/svm_classify.exe");
         //system("C://SVMLight/svmlearn.exe boat_sortie.txt modele");
         //system("C://SVMLight/svmclassify.exe boat_sortie_test.txt modele output.txt");
         sprintf(nomFichier,"test2007/VOCdevkit/VOC2007/ImageSets/Main/%s_test.txt",classes);
         creerGraph(nomFichier,"output.txt");
         //creerGraph("car.txt","output.txt");
         //system("pause");
         //system("shutdown -s -f");
         return 0;

 }
